﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Text.RegularExpressions;
using Core.CommandProcesser;
using Core.Entities;
using Core.Exceptions;
using Core.Formats;
using Core.Reader;
using Core.Enums;
using Core.Writer;
using Core.ReadWriter;
using Core.Tools;

namespace Core
{
    /// <summary>
    /// Core 基础处理程序
    /// </summary>
    public abstract class BaseProcess
    {
        #region -- Const --
        /// <summary>
        /// 表示已完成代码
        /// </summary>
        public const int CodeOk = 0x0;
        /// <summary>
        /// 表示已成功取得结果
        /// </summary>
        public const int CodeSuccess = 0x0;
        /// <summary>
        /// 表示已失败 (此情况一般抛出异常)
        /// </summary>
        public const int CodeError = 0x1;
        /// <summary>
        /// 表示需要询问用户是否确定某些操作
        /// </summary>
        public const int CodeConfirm = 0x2;
        /// <summary>
        /// 表示已完成某些操作，但还是需要重点提醒用户
        /// </summary>
        public const int CodeWarning = 0x4;
        /// <summary>
        /// 表示要求客户端跳转 URL
        /// </summary>
        public const int CodeRedirect = 0x8;
        /// <summary>
        /// 表示用户未授权
        /// </summary>
        public const int CodeUnauthorized = 0x10;
        /// <summary>
        /// 表示已超时
        /// </summary>
        public const int CodeTimeout = 0x20;
        #endregion

        #region -- Static --

        /// <summary>
        /// 缓存命令
        /// </summary>
        private static readonly Dictionary<string, CommandInfo> Commands;
        /// <summary>
        /// 命令缓存的分组。
        /// </summary>
        private static readonly Dictionary<string, CacheCommandsMapInfo> CacheCommandsMap;
        /// <summary>
        /// CommandBuffer 写入锁
        /// </summary>
        private static readonly object CommandsLock;
        /// <summary>
        /// 储存命令处理器
        /// </summary>
        private static readonly Dictionary<string, BaseCommandProcesser> CommandProcessers;
        /// <summary>
        /// CommandProcessers 锁
        /// </summary>
        private static readonly object CommandProcessersLock;
        /// <summary>
        /// 缓存全局配置项
        /// </summary>
        private static readonly ParamsDictionary<string, ConfigInfo> GlobalConfigs;
        /// <summary>
        /// 全局配置项缓存锁
        /// </summary>
        private static readonly object GlobalConfigsLock;
        /// <summary>
        /// 缓存触发器
        /// </summary>
        private static Triggers Triggers;
        /// <summary>
        /// 触发器缓存锁
        /// </summary>
        private static readonly object TriggersLock;
        /// <summary>
        /// 默认格式化器
        /// </summary>
        public static IDocumentFormat DefaultFormat;
        /// <summary>
        /// 用于保存磁盘缓存内容的格式化器。
        /// </summary>
        public static IDocumentFormat CacheFormat;

        /// <summary>
        /// 静态构造函数
        /// </summary>
        static BaseProcess()
        {
            try
            {
                Commands = new Dictionary<string, CommandInfo>();
                CacheCommandsMap = new Dictionary<string, CacheCommandsMapInfo>();
                CommandsLock = new object();

                GlobalConfigs = new ParamsDictionary<string, ConfigInfo>(ParamsDictionaryOption.AllowRepeat);
                GlobalConfigsLock = new object();

                CommandProcessers = new Dictionary<string, CommandProcesser.BaseCommandProcesser>();
                CommandProcessersLock = new object();
                
                TriggersLock = new object();

                DefaultFormat = new EsonFormat();
                CacheFormat = new EsonFormat();
            }
            catch (Exception e)
            {
                Logs.Exception(e);
            }
        }

        /// <summary>
        /// 参数类型转换
        /// </summary>
        /// <typeparam name="T">目标类型</typeparam>
        /// <param name="Name">参数名</param>
        /// <param name="Value">参数值</param>
        /// <returns>返回该参数值的目标类型值</returns>
        private static T Cast<T>(string Name, object Value)
        {
            try
            {
                return (T)Value;
            }
            catch (NullReferenceException)
            {
                throw new Exception("请求的数据无效，因为参数 -- " + Name + " -- 不能为 Null");
            }
            catch (InvalidCastException)
            {
                throw new Exception("请求的数据无效，因为参数 -- " + Name + " -- 的格式应是 -- " + typeof(T).Name + " --，而不是 -- " + Value.GetType().Name);
            }
        }

        /// <summary>
        /// 添加命令处理器。添加后当执行的命令类型与该处理器的类型一致时将使用该处理器来执行这个命令。
        /// </summary>
        /// <param name="Type">命令处理器类型</param>
        /// <param name="CommandProcesser">命令处理器</param>
        public static void AddCommandProcesser(string Type, CommandProcesser.BaseCommandProcesser CommandProcesser)
        {
            if (CommandProcessers.ContainsKey(Type))
            {
                goto Error;
            }

            lock (CommandProcessersLock)
            {
                if (CommandProcessers.ContainsKey(Type))
                {
                    goto Error;
                }

                CommandProcessers.Add(Type, CommandProcesser);
                return;
            }

            Error:
            throw new Exception("该命令处理程序已经添加过 -- " + Type);
        }

        /// <summary>
        /// 删除指定命令的缓存，使这个命令在下次执行时重新加载。
        /// </summary>
        /// <param name="CommandName">需要删除缓存的命令名称</param>
        public static void RemoveCommandBuffer(string CommandName)
        {
            if (Commands.ContainsKey(CommandName))
            {
                lock (CommandsLock)
                {
                    CommandInfo CommandInfo;

                    if (Commands.TryGetValue(CommandName, out CommandInfo))
                    {
                        if (CommandInfo.CacheTokens != null && CommandInfo.CacheTokens.Length != 0)
                        {
                            if ((CommandInfo.Sign & CommandSigns.Select) != 0)
                            {
                                Dictionary<string, CommandInfo> UpdateCommands = new Dictionary<string, CommandInfo>();

                                foreach (var Item in CommandInfo.CacheTokens)
                                {
                                    CacheCommandsMapInfo CCMInfo = CacheCommandsMap[Item];

                                    CCMInfo.ReadCommands.Remove(CommandInfo);

                                    foreach (var UCItem in CCMInfo.UpdateCommands)
                                    {
                                        UpdateCommands[UCItem.Name] = UCItem;
                                    }
                                }

                                foreach (var Item in UpdateCommands.Values)
                                {
                                    ReloadSimilarCacheCommands(Item);
                                }
                            }
                            else
                            {
                                foreach (var Item in CommandInfo.CacheTokens)
                                {
                                    CacheCommandsMapInfo CCMInfo = CacheCommandsMap[Item];

                                    CCMInfo.UpdateCommands.Remove(CommandInfo);
                                }
                            }
                        }

                        Commands.Remove(CommandName);
                    }
                }
            }
        }

        /// <summary>
        /// 重新加载更新命令的同类查询命令。
        /// </summary>
        /// <param name="CommandInfo">需要重新加载的更新命令</param>
        private static void ReloadSimilarCacheCommands(CommandInfo CommandInfo)
        {
            Dictionary<string, CommandInfo> ReadCommands = new Dictionary<string, CommandInfo>();

            foreach (var CTItem in CommandInfo.CacheTokens)
            {
                CacheCommandsMapInfo CCMInfo = CacheCommandsMap[CTItem];

                foreach (var RCItem in CCMInfo.ReadCommands)
                {
                    ReadCommands[RCItem.Name] = RCItem;
                }
            }

            CommandInfo[] SimilarCacheCommands = new CommandInfo[ReadCommands.Count];

            ReadCommands.Values.CopyTo(SimilarCacheCommands, 0);

            CommandInfo.SimilarCacheCommands = SimilarCacheCommands;
        }

        #endregion

        #region -- Fields --

        /// <summary>
        /// 数据读取器集合 
        /// </summary>
        private readonly List<IDataReader> Readers;
        /// <summary>
        /// 储存 HTTP 请求参数和程序自定参数
        /// </summary>
        public readonly ParamsDictionary<string, object> Params;
        /// <summary>
        /// 格式化器
        /// </summary>
        public IDocumentFormat Format;
        /// <summary>
        /// 命令执行结果是否来自缓存
        /// </summary>
        public bool FromCache;

        #endregion

        /// <summary>
        /// 构造函数用于初始化对象
        /// </summary>
        public BaseProcess()
        {
            Readers = new List<IDataReader>();
            Params = new ParamsDictionary<string, object>(ParamsDictionaryOption.AllowRepeat);
        }

        /// <summary>
        /// 初始化触发器
        /// </summary>
        private void InitializeTriggers()
        {
            if (Triggers == null)
            {
                lock (TriggersLock)
                {
                    if (Triggers == null)
                    {
                        Triggers = new Triggers();

                        ReloadTriggers();
                    }
                }
            }
        }

        /// <summary>
        /// 在命令执行前对命令和参数进行检查。
        /// 重写可对命令进行授权控制。
        /// </summary>
        /// <param name="CommandInfo">需要检查的命令</param>
        public virtual void CheckCommand(CommandInfo CommandInfo)
        {
            foreach (var Item in CommandInfo.Params)
            {
                /* 不检测系统内置参数 */
                if ((Item.Sign & CommandParamSigns.SystemParam) != 0)
                {
                    continue;
                }

                object Value = this[Item.Name];

                /* 如果参数值是空，那么如果该参数允许为空就跳过，不允许则发生异常 */
                if (Value == null)
                {
                    if ((Item.Sign & CommandParamSigns.AllowNull) == 0)
                    {
                        goto CannotBeNull;
                    }

                    continue;
                }

                if (Item.Type == ParamTypes.String && "".Equals(Value) && (Item.Sign & CommandParamSigns.AllowNull) == 0)
                {
                    goto CannotBeNull;
                }

                /* 判断参数类型，如果类型不匹配则尝试转换，转换失败则发生异常 */
                try
                {
                    object CastedValue = TypeHelper.CastParameterType(Value, Item.Type);
                    
                    if (CastedValue != Value)
                    {
                        this[Item.Name] = CastedValue;
                    }

                    continue;
                }
                catch (Exception)
                {
                    throw new ParamFormatException(StringHelper.Format("参数 '{0}', 的定义类型 '{1}' 与实际类型 '{2}' 不匹配！", Item.Name, Convert.ToString(Item.Type), Value.GetType().Name));
                }

                CannotBeNull:
                throw new ParamFormatException(StringHelper.Format("参数 '{0}' 不能为 Null！", Item.Name));
            }
        }
        
        /// <summary>
        /// 处理请求基本请求，并将结果写入到文本中
        /// </summary>
        /// <param name="Writer">文本写入器</param>
        public void Process(TextWriter Writer)
        {
            try
            {
                /* 初始化触发器 */
                if (Triggers == null)
                {
                    InitializeTriggers();

                    ReloadGlobalConfigs();
                }

                /* 获得命令名称，如果为空则发生异常 */
                var Command = GetItem<string>("Command");

                if (Command == null)
                {
                    throw new Exception("参数 -- Command -- 是必须的");
                }

                /* 尝试获得命令信息。GetCommand 函数在获得失败后会发生异常，所以在这里就不需要检测了。 */
                var CommandInfo = GetCommand(Command);

                /* 如果命令标识了不能由用户调用则发生异常。 */
                if ((CommandInfo.Sign & CommandSigns.NoCall) != 0)
                {
                    throw new Exception("您不能执行该命令 -- " + Command);
                }

                /* 在命令执行前对命令进行检查 */
                CheckCommand(CommandInfo);

                /* 调用前置触发器 */
                if (CommandInfo.BeforeTriggers != null && CommandInfo.BeforeTriggers.Length != 0)
                {
                    foreach (var Item in CommandInfo.BeforeTriggers)
                    {
                        ProcessTrigger(CommandInfo, Item, Writer);
                    }
                }

                /* 执行命令 */
                ProcessCommand(CommandInfo, Reader =>
                {
                    /* 调用后置触发器 */
                    if (CommandInfo.AfterTriggers != null && CommandInfo.AfterTriggers.Length != 0)
                    {
                        foreach (var Item in CommandInfo.AfterTriggers)
                        {
                            ProcessTrigger(CommandInfo, Item, Writer);
                        }
                    }

                    /* 处理命令执行结果 */
                    Finish(Reader, Writer);
                });
            }
            catch (Exception e)
            {
                /* 处理异常 */
                ProcessException(e, Reader =>
                {
                    /* 处理异常处理结果 */
                    Finish(Reader, Writer);
                });
            }

        }

        /// <summary>
        /// 处理触发器
        /// </summary>
        /// <param name="Source">触发源信息</param>
        /// <param name="Trigger">需要处理的触发器</param>
        /// <param name="Writer">内容写入器</param>
        protected virtual void ProcessTrigger(CommandInfo Source, CommandInfo Trigger, TextWriter Writer)
        {
            ProcessCommand(Trigger, TriggerWriter.Instance);
        }

        /// <summary>
        /// 完成处理，写入数据
        /// </summary>
        /// <param name="Reader">命令执行后得到的数据读取器</param>
        /// <param name="Writer">文本写入器</param>
        public virtual void Finish(IDataReader Reader, TextWriter Writer)
        {
            /* 如果当前格式化器为空，则使用默认格式化器 */
            if (Format == null)
            {
                Format = DefaultFormat;
            }

            Format.Encode(Reader, Writer);

            Params.Clear();

            Format = null;

            FromCache = false;
        }

        /// <summary>
        /// 尝试获得命令的缓存结果。
        /// </summary>
        /// <param name="CommandInfo">命令信息。</param>
        /// <param name="Callback">回掉函数</param>
        /// <param name="ParamsSign">命令参数信息。</param>
        /// <returns>返回一个 bool 值，表示是否读取成功缓存。</returns>
        public bool TryGetCommandCache(CommandInfo CommandInfo, Action<IDataReader> Callback, out object[] ParamsSign)
        {
            ParamsSign = null;

            if ((CommandInfo.Sign & CommandSigns.UseCache) != 0)
            {
                ParamsSign = CommandInfo.InternalProcesser.GetCacheParamsSign(this, CommandInfo);

                CommandCacheInfo CacheInfo;

                if (CommandInfo.Caches.TryGetValue(ParamsSign, out CacheInfo))
                {
                    ++CacheInfo.UseCount;

                    CacheInfo.LastUseTime = DateTime.Now;

                    if ((CommandInfo.Sign & CommandSigns.MemoryCache) != 0)
                    {
                        TableReadWriter DataReader = (TableReadWriter)CacheInfo.CacheTag;

                        DataReader.Reset();

                        Callback(DataReader);

                        return true;
                    }
                    else if((CommandInfo.Sign & CommandSigns.DiskCache) != 0)
                    {
                        TableReadWriter DataReader = new TableReadWriter();

                        string CachePath = (string)CacheInfo.CacheTag;
                        
                        if (File.Exists(CachePath))
                        {
                            using (FileStream Fs = new FileStream(CachePath, FileMode.Open, FileAccess.Read))
                            {
                                using (StreamReader Sr = new StreamReader(Fs))
                                {
                                    string CacheCentent = Sr.ReadToEnd();

                                    CacheFormat.Decode(CacheCentent, DataReader);

                                    Callback(DataReader);

                                    return true;
                                }
                            }
                        }
                        else
                        {
                            // 缓存文件被删除，则清除缓存信息。
                            lock (CommandInfo.CachesLock)
                            {
                                CommandInfo.Caches.Remove(ParamsSign);
                            }
                        }
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// 保存命令的缓存结果。
        /// </summary>
        /// <param name="CommandInfo">命令信息。</param>
        /// <param name="ParamsSign">命令参数信息。</param>
        /// <param name="Reader">需要保存的结果读取器。</param>
        public void SaveCommandCache(CommandInfo CommandInfo, object[] ParamsSign, ref IDataReader Reader)
        {
            if (!CommandInfo.Caches.ContainsKey(ParamsSign))
            {
                lock (CommandInfo.CachesLock)
                {
                    if (!CommandInfo.Caches.ContainsKey(ParamsSign))
                    {
                        TableReadWriter CacheReadWriter = new TableReadWriter();

                        RWHelper.Copy(Reader, CacheReadWriter);

                        Reader = CacheReadWriter;

                        if ((CommandInfo.Sign & CommandSigns.MemoryCache) != 0)
                        {
                            CommandInfo.Caches[ParamsSign] = new CommandCacheInfo(CacheReadWriter);
                        }
                        else if ((CommandInfo.Sign & CommandSigns.DiskCache) != 0)
                        {
                            string CacheDirectory = GetConfigItem<string>("Path_CacheDirectory");
                            string CacheFileName = Guid.NewGuid().ToString("N");

                            string CacheFileSaveDirectory = Path.Combine(CacheDirectory, CommandInfo.Name);

                            IOHelper.CreateDirectory(new DirectoryInfo(CacheFileSaveDirectory));

                            string CacheValuePath = Path.Combine(CacheFileSaveDirectory, CacheFileName + ".value");

                            using (FileStream Fs = new FileStream(CacheValuePath, FileMode.Create, FileAccess.Write))
                            {
                                using (StreamWriter Sw = new StreamWriter(Fs))
                                {
                                    CacheFormat.Encode(CacheReadWriter, Sw);
                                }
                            }

                            CacheReadWriter.Reset();

                            CommandInfo.Caches[ParamsSign] = new CommandCacheInfo(CacheValuePath);
                        }
                    }
                }
            }

        }

        /// <summary>
        /// 匹配命令执行器，然后执行命令
        /// </summary>
        /// <param name="CommandInfo">需要执行的命令</param>
        /// <param name="Callback">回调函数</param>
        public void ProcessCommand(CommandInfo CommandInfo, Action<IDataReader> Callback)
        {
            if ((CommandInfo.Sign & CommandSigns.Select) != 0 && (CommandInfo.Sign & CommandSigns.UseCache) != 0)
            {
                object[] CacheParamsInfo;

                if (!TryGetCommandCache(CommandInfo, DataReader =>
                    {
                        FromCache = true;

                        Callback(DataReader);
                    }, out CacheParamsInfo))
                {
                    CommandInfo.InternalProcesser.Process(this, CommandInfo, DataReader =>
                    {
                        SaveCommandCache(CommandInfo, CacheParamsInfo, ref DataReader);

                        Callback(DataReader);
                    });
                }
            }
            else
            {
                if ((CommandInfo.Sign & CommandSigns.Select) == 0 &&
                    CommandInfo.SimilarCacheCommands != null &&
                    CommandInfo.SimilarCacheCommands.Length != 0)
                {
                    foreach (var Item in CommandInfo.SimilarCacheCommands)
                    {
                        if (Item.Caches != null)
                        {
                            Item.Caches.Clear();
                        }
                    }
                }

                CommandInfo.InternalProcesser.Process(this, CommandInfo, Callback);
            }
        }

        /// <summary>
        /// 匹配命令执行器，然后执行命令
        /// </summary>
        /// <param name="CommandInfo">需要执行的命令</param>
        /// <param name="Writer">数据写入器</param>
        public void ProcessCommand(CommandInfo CommandInfo, IDataWriter Writer)
        {
            if ((CommandInfo.Sign & CommandSigns.Select) != 0 && (CommandInfo.Sign & CommandSigns.UseCache) != 0)
            {
                object[] CacheParamsInfo;

                if (!TryGetCommandCache(CommandInfo, DataReader =>
                    {
                        FromCache = true;

                        RWHelper.Copy(DataReader, Writer);
                    }, out CacheParamsInfo))
                {
                    CommandInfo.InternalProcesser.Process(this, CommandInfo, DataReader =>
                    {
                        SaveCommandCache(CommandInfo, CacheParamsInfo, ref DataReader);

                        RWHelper.Copy(DataReader, Writer);
                    });
                }
            }
            else
            {
                if ((CommandInfo.Sign & CommandSigns.Select) == 0 &&
                    CommandInfo.SimilarCacheCommands != null &&
                    CommandInfo.SimilarCacheCommands.Length != 0)
                {
                    foreach (var Item in CommandInfo.SimilarCacheCommands)
                    {
                        if (Item.Caches != null)
                        {
                            Item.Caches.Clear();
                        }
                    }
                }

                CommandInfo.InternalProcesser.Process(this, CommandInfo, Writer);
            }
        }

        /// <summary>
        /// 匹配命令执行器，然后执行命令
        /// </summary>
        /// <param name="CommandInfo">需要执行的命令</param>
        /// <param name="Object">.Net 对象，执行后将结果填充到这个对象中</param>
        public void ProcessCommand(CommandInfo CommandInfo, object Object)
        {
            using (var ObjectWriter = BaseReadWriter.Create(Object))
            {
                ProcessCommand(CommandInfo, ObjectWriter);
            }
        }

        /// <summary>
        /// 匹配命令执行器，然后执行命令
        /// </summary>
        /// <typeparam name="T">得到结果的数据类型</typeparam>
        /// <param name="CommandInfo">需要执行的命令</param>
        /// <returns></returns>
        public T ProcessCommand<T>(CommandInfo CommandInfo)
        {
            using (var ObjectWriter = BaseReadWriter.Create(typeof(T)))
            {
                ProcessCommand(CommandInfo, ObjectWriter);

                return (T)ObjectWriter.Content;
            }
        }

        /// <summary>
        /// 处理程序发生的异常
        /// </summary>
        /// <param name="e">异常欣喜</param>
        /// <param name="Callback">回调函数</param>
        protected virtual void ProcessException(Exception e, Action<IDataReader> Callback)
        {
            var ResultDictionary = new Dictionary<string, object>();

            if (e is UnauthorizedException)
            {
                ResultDictionary["Code"] = CodeUnauthorized;
                ResultDictionary["Exception"] = e.GetType().Name;
                ResultDictionary["Msg"] = e.Message;
            }
            else if (e is SqlException)
            {
                ResultDictionary["Code"] = CodeError;
                switch (((SqlException)e).Number)
                {
                    case -2:
                        ResultDictionary["Exception"] = "TimeoutException";
                        ResultDictionary["Msg"] = "查询超时！";
                        break;
                    case 8114:
                        ResultDictionary["Exception"] = "InvalidCastException";

                        Match Match = Regex.Match(e.Message, "从数据类型 (?<FromType>[A-Za-z0-9_]+) 转换为 (?<ToType>[A-Za-z0-9_]+) 时出错。");
                        if (Match.Success)
                        {
                            switch (Match.Groups["ToType"].Value)
                            {
                                case "bit":
                                case "int":
                                case "smallint":
                                case "tinyint":
                                case "numeric":
                                case "decimal":
                                case "money":
                                case "smallmoney":
                                case "float":
                                case "real":
                                    ResultDictionary["Msg"] = "输入的“数字”格式不正确！";
                                    break;
                                case "date":
                                case "datetime":
                                    ResultDictionary["Msg"] = "输入的“日期”格式不正确！";
                                    break;
                                default:
                                    ResultDictionary["Msg"] = "输入的“" + Match.Groups["ToType"].Value + "”格式不正确！";
                                    break;
                            }
                        }
                        else
                        {
                            goto default;
                        }
                        break;
                    default:
                        ResultDictionary["Exception"] = e.GetType().Name;
                        ResultDictionary["Source"] = e.Source;
                        ResultDictionary["StackTrace"] = e.StackTrace;
                        ResultDictionary["TargetSite"] = Convert.ToString(e.TargetSite);
                        ResultDictionary["Msg"] = e.Message;
                        break;
                }
            }
            else
            {
                ResultDictionary["Code"] = CodeError;
                ResultDictionary["Exception"] = e.GetType().Name;
                ResultDictionary["Source"] = e.Source;
                ResultDictionary["StackTrace"] = e.StackTrace;
                ResultDictionary["TargetSite"] = Convert.ToString(e.TargetSite);
                ResultDictionary["Msg"] = e.Message;
            }

            Callback(new DictionaryReadWriter(ResultDictionary));
        }

        /// <summary>
        /// 尝试通过命令名称获得命令信息，框架使用者必须实现该函数。
        /// </summary>
        /// <param name="CommandInfo">命令信息。该对象只提供命令名称，其他信息均为默认值。</param>
        /// <returns>如果获得命令信息成功返回真，否则返回假。返回真时必须对命令信息中的其他字段进行赋值。</returns>
        protected abstract bool TryGetCommand(CommandInfo CommandInfo);

        /// <summary>
        /// 获得所有触发器函数，需重写。
        /// </summary>
        /// <returns>返回触发器集合</returns>
        protected virtual TriggerInfo[] GetTriggers()
        {
            return new TriggerInfo[0];
        }

        /// <summary>
        /// 重新加载所有触发器
        /// </summary>
        public void ReloadTriggers()
        {
            lock (Triggers)
            {
                Triggers.LoadTriggers(GetTriggers());

                // 清除已绑定的触发器
                lock (CommandsLock)
                {
                    foreach (var Item in Commands)
                    {
                        Item.Value.BeforeTriggers = null;
                        Item.Value.AfterTriggers = null;
                    }
                }
            }
        }

        /// <summary>
        /// 获取所有全局配置项信息。
        /// </summary>
        /// <returns>返回一个配置项集合。</returns>
        protected abstract ConfigInfo[] GetGlobalConfigs();

        /// <summary>
        /// 重写加载所有全局配置项
        /// </summary>
        public void ReloadGlobalConfigs()
        {
            lock (GlobalConfigsLock)
            {
                GlobalConfigs.Clear();

                foreach (var Item in GetGlobalConfigs())
                {
                    GlobalConfigs.Add(Item.Name, Item);
                }
            }
        }

        /// <summary>
        /// 获取命令信息，获取失败将发生异常
        /// </summary>
        /// <param name="CommandName">命令名称</param>
        /// <returns></returns>
        public CommandInfo GetCommand(string CommandName)
        {
            CommandInfo CommandInfo = null;

            try
            {
                /* 尝试获得已经缓存中存在的命令信息 */
                if (Commands.TryGetValue(CommandName, out CommandInfo))
                {
                    return CommandInfo;
                }

                /* 命令在缓存中不存在，尝试从使用者重写的 TryGetCommand 函数中获得命令信息 */
                CommandInfo = new CommandInfo(CommandName);

                if (TryGetCommand(CommandInfo))
                {
                    /* 获得命令信息成功 */
                    BaseCommandProcesser CommandProcesser;

                    /* 尝试获得该与该命令类型对应的命令处理器，没有匹配的则发生异常。 */
                    if (!CommandProcessers.TryGetValue(CommandInfo.Type, out CommandProcesser))
                    {
                        throw new Exception("没有该类型命令处理器 -- " + CommandInfo.Type);
                    }

                    /* 指定该命令的命令处理器 */
                    CommandInfo.InternalProcesser = CommandProcesser;

                    /* 调用该命令处理器的初始化命令函数来初始化该命令 */
                    CommandProcesser.Initialization(CommandInfo);

                    /* 获取缓存根集合 */
                    string[] CacheTokens;

                    if (CommandInfo.CacheToken != null)
                    {
                        CacheTokens = CommandInfo.CacheToken.Split(',');

                        int Index = 0;

                        for (int i = 0; i < CacheTokens.Length; i++)
                        {
                            string Item = CacheTokens[i].Trim();

                            if (!string.IsNullOrEmpty(Item))
                            {
                                CacheTokens[Index] = Item;

                                ++Index;
                            }
                        }

                        if (Index != CacheTokens.Length)
                        {
                            Array.Resize(ref CacheTokens, Index);
                        }
                    }
                    else
                    {
                        CacheTokens = new string[0];
                    }

                    CommandInfo.CacheTokens = CacheTokens;

                    /* 在同步环境中保存该命令缓存 */
                    lock (CommandsLock)
                    {
                        if (!Commands.ContainsKey(CommandInfo.Name))
                        {
                            Commands.Add(CommandInfo.Name, CommandInfo);

                            if (CacheTokens.Length != 0)
                            {
                                if ((CommandInfo.Sign & CommandSigns.Select) != 0)
                                {
                                    // 读取命令
                                    Dictionary<string, CommandInfo> UpdateCommands = new Dictionary<string, CommandInfo>();

                                    foreach (var Item in CacheTokens)
                                    {
                                        CacheCommandsMapInfo CCMInfo;

                                        if (!CacheCommandsMap.TryGetValue(Item, out CCMInfo))
                                        {
                                            CCMInfo = new CacheCommandsMapInfo();

                                            CacheCommandsMap.Add(Item, CCMInfo);
                                        }

                                        CCMInfo.ReadCommands.Add(CommandInfo);

                                        foreach (var UCItem in CCMInfo.UpdateCommands)
                                        {
                                            UpdateCommands[UCItem.Name] = UCItem;
                                        }
                                    }

                                    foreach (var Item in UpdateCommands.Values)
                                    {
                                        ReloadSimilarCacheCommands(Item);
                                    }
                                }
                                else
                                {
                                    // 更新命令
                                    Dictionary<string, CommandInfo> ReadCommands = new Dictionary<string, CommandInfo>();

                                    foreach (var Item in CacheTokens)
                                    {
                                        CacheCommandsMapInfo CCMInfo;

                                        if (!CacheCommandsMap.TryGetValue(Item, out CCMInfo))
                                        {
                                            CCMInfo = new CacheCommandsMapInfo();

                                            CacheCommandsMap.Add(Item, CCMInfo);
                                        }

                                        CCMInfo.UpdateCommands.Add(CommandInfo);

                                        foreach (var RCItem in CCMInfo.ReadCommands)
                                        {
                                            ReadCommands[RCItem.Name] = RCItem;
                                        }
                                    }

                                    CommandInfo[] SimilarCacheCommands = new CommandInfo[ReadCommands.Count];

                                    ReadCommands.Values.CopyTo(SimilarCacheCommands, 0);

                                    CommandInfo.SimilarCacheCommands = SimilarCacheCommands;
                                }
                            }
                        }
                        else
                        {
                            CommandInfo = Commands[CommandInfo.Name];
                        }
                    }
                    
                    return CommandInfo;
                }

                /* 获取不成功，发生异常。 */
                throw new Exception("没有定义 -- " + CommandName + " -- 命令");
            }
            finally
            {
                /* 加载触发器 */
                if (CommandInfo != null && CommandInfo.BeforeTriggers == null)
                {
                    lock (TriggersLock)
                    {
                        if (CommandInfo.BeforeTriggers == null)
                        {
                            Triggers.GetTriggers(CommandInfo);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 通过参数名读取内置参数，读取器参数，用户参数或全局参数值。
        /// </summary>
        /// <typeparam name="T">参数值的类型</typeparam>
        /// <param name="Name">参数名</param>
        /// <returns>返回指定类型的参数值</returns>
        public T GetItem<T>(string Name)
        {
            return Cast<T>(Name, this[Name]);
        }

        /// <summary>
        /// 通过参数名读取用户参数的值
        /// </summary>
        /// <typeparam name="T">参数值的类型</typeparam>
        /// <param name="Key">参数名</param>
        /// <returns>返回指定类型的参数值</returns>
        public T GetUserItem<T>(string Key)
        {
            object Result;

            if (Params.TryGetValue(Key, out Result))
            {
                return Cast<T>(Key, Result);
            }

            return default(T);
        }

        /// <summary>
        /// 通过参数名读取全局参数的值
        /// </summary>
        /// <typeparam name="T">参数值的类型</typeparam>
        /// <param name="Key">参数名</param>
        /// <returns>返回指定类型的参数值</returns>
        public T GetConfigItem<T>(string Key)
        {
            ConfigInfo ConfigItem;

            if (GlobalConfigs.TryGetValue(Key, out ConfigItem))
            {
                return Cast<T>(Key, ConfigItem.Value);
            }

            return default(T);
        }

        /// <summary>
        /// 通过参数名读取全局参数的值
        /// </summary>
        /// <typeparam name="T">参数值的类型</typeparam>
        /// <param name="Key">参数名</param>
        /// <returns>返回指定类型的参数值</returns>
        public static T GetGlobalConfig<T>(string Key)
        {
            ConfigInfo ConfigItem;

            if (GlobalConfigs.TryGetValue(Key, out ConfigItem))
            {
                return Cast<T>(Key, ConfigItem.Value);
            }

            return default(T);
        }

        /// <summary>
        /// 通过参数名读取全局参数的值集合
        /// </summary>
        /// <typeparam name="T">参数值的类型</typeparam>
        /// <param name="Key">参数名</param>
        /// <returns>返回指定类型的参数值集合</returns>
        public static T[] GetGlobalItems<T>(string Key)
        {
            var ConfigItems = GlobalConfigs.GetValues(Key);

            T[] Result = new T[ConfigItems.Length];

            int Index = 0;

            foreach (var Item in ConfigItems)
            {
                Result[Index] = Cast<T>(Key, Item);

                ++Index;
            }

            return Result;
        }

        /// <summary>
        /// 通过参数名读取或设置内置参数，读取器参数，用户参数或全局参数值。
        /// </summary>
        /// <param name="Name">参数名</param>
        /// <returns>返回该参数的值，不存在将返回空</returns>
        public virtual object this[string Name]
        {
            get
            {
                /** 获得系统基带参数 */
                switch (Name)
                {
                    case "Now":
                        return DateTime.Now;
                    case "NewGuid":
                        return Guid.NewGuid();
                }

                object Result;

                for (int i = Readers.Count - 1; i >= 0; --i)
                {
                    if (Readers[i].TryGetValue(Name, out Result))
                    {
                        return Result;
                    }
                }

                if (Params.TryGetValue(Name, out Result))
                {
                    return Result;
                }

                ConfigInfo ConfigItem;

                if (GlobalConfigs.TryGetValue(Name, out ConfigItem))
                {
                    return ConfigItem.Value;
                }

                return null;
            }
            set
            {
                Params[Name] = value;
            }
        }

        /// <summary>
        /// 添加数据读取器
        /// </summary>
        /// <param name="Reader">数据读取器</param>
        /// <returns>返回该读取器的索引，可用于移除该读取器</returns>
        public int AddReader(IDataReader Reader)
        {
            Readers.Add(Reader);

            return Readers.Count - 1;
        }

        /// <summary>
        /// 移除数据读取器
        /// </summary>
        /// <param name="Index">数据读取器索引</param>
        public void RemoveReader(int Index)
        {
            Readers.RemoveAt(Index);
        }

        /// <summary>
        /// 为 Params 创建一个读写器
        /// </summary>
        /// <returns>返回 Params 的读写器</returns>
        public DictionaryReadWriter CreateParamsReadWriter()
        {
            return new DictionaryReadWriter(typeof(ParamsDictionary<string, object>), Params, typeof(string), typeof(object), RWSigns.ChangeType | RWSigns.Property);
        } 
    }
}